﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Defect_Tracking_System.Helpers;
using System.Transactions;

namespace Defect_Tracking_System.Models
{
    public class GroupManagement
    {
        public IQueryable<Group> GetAllGroup()
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                return from Group in Entities.Groups
                       where Group.GroupName != "System"
                       orderby Group.GroupName
                       select Group;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IQueryable<Group> FindGroup(string keyWord)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                return from Group in Entities.Groups
                       where Group.GroupName.ToLower().Contains(keyWord.ToLower()) && Group.GroupName != "System"
                       orderby Group.GroupName
                       select Group;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Group GetGroup(string groupId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                Guid GroupId;
                Guid.TryParse(groupId, out GroupId);
                return Entities.Groups.FirstOrDefault(g => g.GroupId == GroupId);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int GetNumberOfMemberInGroup(Guid GroupId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                return Entities.Accounts.Where(a => a.GroupId == GroupId).Count();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int GetNumberOfProjectInGroup(Guid GroupId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                return Entities.Projects.Where(p => p.Account.GroupId == GroupId).Count();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int GetNumberOfDefectInGroup(Guid GroupId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                return Entities.Defects.Where(d => d.AccountCreator.GroupId == GroupId).Count();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int GetTotalAttachmentSizeInGroup(Guid GroupId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                var attachs = Entities.Attachments.Where(a => a.Account.GroupId == GroupId);
                if (attachs.Count() > 0)
                {
                    return attachs.Sum(a => a.Size);
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void EnableDisableGroup(string groupId, string action)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid id;
            Guid.TryParse(groupId, out id);

            try
            {
                Group group = Entities.Groups.FirstOrDefault(g => g.GroupId == id);
                if (group != null)
                {
                    if (action.Equals("enable", StringComparison.OrdinalIgnoreCase))
                    {
                        group.IsActived = true;
                    }
                    else if (action.Equals("disable", StringComparison.OrdinalIgnoreCase))
                    {
                        group.IsActived = false;
                    }
                    else
                    {
                        if (group.IsActived)
                        {
                            group.IsActived = false;
                        }
                        else
                        {
                            group.IsActived = true;
                        }
                    }
                    Entities.SaveChanges();
                }
                else
                {
                    throw new Exception("Sorry, this group not exist");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void DeleteGroup(string groupId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();
            try
            {
                AccountManagement AccountManager = AccountManagement.GetInstance();
                ProjectManagement ProjectManager = ProjectManagement.GetInstance();
                ClientManagement ClientManager = ClientManagement.GetInstance();

                Guid id = Guid.Parse(groupId);

                Group group = Entities.Groups.FirstOrDefault(g => g.GroupId == id);
                if (group != null)
                {
                    var accounts = Entities.Accounts.Where(a => a.GroupId == group.GroupId).ToList();
                    var clients = ClientManager.GetClients(groupId).ToList();
                    if (accounts.Count() > 0)
                    {
                        var projects = ProjectManager.GetProjects(accounts.FirstOrDefault().UserName).ToList();
                        foreach (Project project in projects)
                        {
                            ProjectManager.DeleteProject(project.ProjectId.ToString());
                            ProjectManager.UnlockProject(project.ProjectId.ToString());
                        }
                    }
                    foreach (Account account in accounts)
                    {
                        AccountManager.DeleteUser(account.UserName.ToString());
                    }
                    foreach (Client client in clients)
                    {
                        ClientManager.DeleteClient(client);
                    }
                    Entities.Groups.DeleteObject(group);
                    Entities.SaveChanges();
                }
                else
                {
                    throw new Exception("Sorry, this group not exist.");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

    public class GroupModel
    {
        public string GroupId { get; set; }
        public string GroupName { get; set; }
        public int NumberOfMember { get; set; }
        public int NumberOfProject { get; set; }
        public int NumberOfDefect { get; set; }
        public int TotalAttachmentSize { get; set; }
        public string CreatedDate { get; set; }
        public string Creator { get; set; }
        public bool IsActive { get; set; }
    }

    public class GroupListModel
    {
        public List<GroupModel> Groups = new List<GroupModel>();
        public int PageIndex { get; private set; }
        public int TotalPages { get; private set; }
        public bool HasNext { get; private set; }
        public bool HasPrevious { get; private set; }
        public string KeyWord { get; set; }

        public GroupListModel(string keyWord, int PageIndex)
        {
            DefectTrackingSystemEntities entities = new DefectTrackingSystemEntities();
            IQueryable<Group> groups;
            GroupManagement groupManager = new GroupManagement();
            this.KeyWord = keyWord;
            if (keyWord != "Search Group")
            {
                groups = groupManager.FindGroup(keyWord);
            }
            else
            {
                groups = groupManager.GetAllGroup();
            }
            PaginatedList<Group> GroupsList = new PaginatedList<Group>(groups, PageIndex, 10);
            this.PageIndex = GroupsList.PageIndex;
            TotalPages = GroupsList.TotalPages;
            HasNext = GroupsList.hasNext;
            HasPrevious = GroupsList.hasPrevious;
            foreach (Group group in GroupsList.ToList())
            {
                GroupModel model = new GroupModel();
                model.GroupId = group.GroupId.ToString();
                model.GroupName = group.GroupName;
                model.NumberOfMember = groupManager.GetNumberOfMemberInGroup(group.GroupId);
                model.NumberOfProject = groupManager.GetNumberOfProjectInGroup(group.GroupId);
                model.NumberOfDefect = groupManager.GetNumberOfDefectInGroup(group.GroupId);
                model.TotalAttachmentSize = groupManager.GetTotalAttachmentSizeInGroup(group.GroupId);
                model.CreatedDate = String.Format("{0:g}", group.CreatedDate);
                model.Creator = entities.Accounts.FirstOrDefault(a => a.GroupId == group.GroupId && a.Role == "Group Admin").UserName;
                model.IsActive = group.IsActived;
                Groups.Add(model);
            }
        }
    }
}